package com.csg.ses.service.ses.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csg.ses.common.utils.CommonUtil;
import com.csg.ses.common.utils.MybatisPlusUtil;
import com.csg.ses.common.utils.SnowFlakeUtil;
import com.csg.ses.dao.ses.MenuItemDao;
import com.csg.ses.entity.ses.MenuItemEntity;
import com.csg.ses.service.ses.MenuItemService;
import com.csg.ses.vo.common.IdListVo;
import com.csg.ses.vo.common.Result;
import com.csg.ses.vo.common.ResultStatus;
import com.csg.ses.vo.login.UserContext;
import com.csg.ses.vo.login.UserView;
import com.csg.ses.vo.menu.ItemVo;
import com.csg.ses.vo.menu.MenuItemVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 菜单
 * @author wangjun
 * @date 2020/11/16
 */
@Service
@RequiredArgsConstructor
public class MenuItemServiceImpl extends ServiceImpl<MenuItemDao, MenuItemEntity> implements MenuItemService {
    private final MenuItemDao menuItemDao;

    @Override
    public Result retrieve() {
        try {
            UserView userView = UserContext.getUserView();
            List<MenuItemEntity> menuList = menuItemDao.getMenuRights(userView.getLoginId());
            List<MenuItemVo> mvList = this.transToTree(menuList, "0");
            return new Result(mvList, ResultStatus.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    @Override
    public Result retrieveAll() {
        try {
            List<MenuItemEntity> menuList = menuItemDao.getAllMenus();
            List<MenuItemEntity> list = new ArrayList<>();
            for (MenuItemEntity item : menuList) {
                if (item.getId().equals("2") || item.getParentCode().equals("GSGL")) {
                    list.add(item);
                }
            }
            if(!UserContext.getUserView().getLoginId().equals("1")) {
                menuList.removeAll(list);
            }
            List<MenuItemVo> mvList = this.transToTree(menuList, "0");

            return new Result(mvList, ResultStatus.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    @Override
    public Result pageData(MenuItemEntity item, Long current, Long size) {
        try {
            Page<MenuItemEntity> page = MybatisPlusUtil.initPage(current, size, true);
            QueryWrapper<MenuItemEntity> qw = new QueryWrapper();
            if (!CommonUtil.isEmpty(item.getUseFlag())) {
                qw.eq("use_flag", item.getUseFlag());
            }
            if (!CommonUtil.isEmpty(item.getMenuCode())) {
                qw.eq("menu_code", item.getMenuCode());
            }
            if (!CommonUtil.isEmpty(item.getMenuName())) {
                qw.like("menu_name", item.getMenuName());
            }
            if (!CommonUtil.isEmpty(item.getMenuUrl())) {
                qw.like("menu_url", item.getMenuUrl());
            }
            if (!CommonUtil.isEmpty(item.getIsExtra())) {
                qw.eq("is_extra", item.getIsExtra());
            }
            if (!CommonUtil.isEmpty(item.getParentCode())) {
                qw.eq("parent_code", item.getParentCode());
            }
            qw.orderByAsc("order_code");
            return new Result(menuItemDao.selectPage(page, qw), ResultStatus.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    @Override
    public Result tree() {
        try {
            QueryWrapper<MenuItemEntity> qw = new QueryWrapper<>();
            qw.eq("use_flag", "Y");
            qw.orderByAsc("order_code");
            List<MenuItemEntity> menuList = menuItemDao.selectList(qw);

            MenuItemEntity rootItem = new MenuItemEntity();
            rootItem.setMenuCode("0");
            rootItem.setParentCode("root");
            rootItem.setOrderCode("00");
            rootItem.setMenuName("菜单选择");
            menuList.add(rootItem);

            List<MenuItemVo> mvList = this.transToTree(menuList, "root");
            return new Result(mvList, ResultStatus.SUCCESS);
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    @Override
    public Result getByParentCode(String parentCode) {
        try {
            UserView userView = UserContext.getUserView();
            List<MenuItemEntity> menuList = menuItemDao.getByParentCode(userView.getLoginId(), parentCode);
            return new Result(menuList, ResultStatus.SUCCESS);
        } catch (Exception e) {
            return new Result(ResultStatus.FAILED);
        }
    }

    @Override
    @Transactional
    public Result del(IdListVo idList) {
        try {
            if (idList != null && idList.getIdList().size() > 0) {
                int num = menuItemDao.deleteBatchIds(idList.getIdList());
                return new Result(num + "条记录删除成功！", ResultStatus.SUCCESS);
            } else {
                return new Result("未指定需要删除的记录！", ResultStatus.BIZ_FAILED);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(ResultStatus.FAILED);
        }
    }

    @Override
    @Transactional
    public Result save(ItemVo itemVo) {
        if (itemVo != null && itemVo.getMenuItemList().size() > 0) {
            for (MenuItemEntity item : itemVo.getMenuItemList()) {
                if (CommonUtil.isEmpty(item.getParentCode())) {
                    throw new RuntimeException("上级编码不能为空！");
                } else {
                    //自动生成menu_code和order_code
                    MenuItemEntity me = menuItemDao.generateMenuCodeAndOrderCode(item.getParentCode());
                    item.setMenuCode(CommonUtil.isEmpty(item.getMenuCode()) ? me.getMenuCode() : item.getMenuCode());
                    item.setOrderCode(CommonUtil.isEmpty(item.getOrderCode()) ? me.getOrderCode() : item.getOrderCode());

                    //判断数据库是否存在当前menu_code的菜单项
                    QueryWrapper<MenuItemEntity> qw = new QueryWrapper();
                    qw.eq("menu_code", item.getMenuCode());
                    MenuItemEntity menu = menuItemDao.selectOne(qw);
                    if (menu != null) {
                        item.setId(menu.getId());
                    }

                    //插入或更新
                    if (!CommonUtil.isEmpty(item.getId())) {
                        menuItemDao.updateById(item);
                    } else {
                        item.setId(SnowFlakeUtil.nextStringId());
                        item.setUseFlag(CommonUtil.isEmpty(item.getUseFlag()) ? "Y" : item.getUseFlag());
                        menuItemDao.insert(item);
                    }
                }
            }
            return this.retrieve();
        } else {
            return new Result("未传入需要保存的记录！", ResultStatus.BIZ_FAILED);
        }
    }

    @Override
    public Result getById(String id) {
        if (!CommonUtil.isEmpty(id)) {
            return new Result(menuItemDao.selectById(id), ResultStatus.SUCCESS);
        } else {
            throw new RuntimeException("id不能为空！");
        }
    }

    /**
     * 将菜单转成树形结构的list集合
     * @param menuList
     * @param rootCode
     * @return
     */
    public List<MenuItemVo> transToTree(List<MenuItemEntity> menuList, String rootCode) {
        List<MenuItemVo> treeList = new ArrayList<MenuItemVo>();
        for (MenuItemEntity item: menuList) {
            if (rootCode.equals(item.getParentCode())) {
                treeList.add(this.findChildrenMenu(item, menuList));
            }
        }
        return treeList;
    }

    /**
     * 递归查找子菜单
     * @param item
     * @param menuList
     * @return
     */
    public MenuItemVo findChildrenMenu(MenuItemEntity item, List<MenuItemEntity> menuList) {
        MenuItemVo menuVo = this.initMenuVo(item);
        for (MenuItemEntity node: menuList) {
            if (item.getMenuCode().equals(node.getParentCode())) {
                if (menuVo.getChildren() == null) {
                    menuVo.setChildren(new ArrayList<MenuItemVo>());
                }
                menuVo.getChildren().add(findChildrenMenu(node, menuList));
            }
        }
        return menuVo;
    }

    /**
     * 初始化vo
     * @param menuItem
     * @return
     */
    public MenuItemVo initMenuVo(MenuItemEntity menuItem) {
        MenuItemVo vo = new MenuItemVo();
        vo.setId(menuItem.getId());
        vo.setRouterName(menuItem.getRouterName());
        vo.setMenuCode(menuItem.getMenuCode());
        vo.setMenuName(menuItem.getMenuName());
        vo.setParentCode(menuItem.getParentCode());
        vo.setUseFlag(menuItem.getUseFlag());
        vo.setOrderCode(menuItem.getOrderCode());
        vo.setIcon(menuItem.getIcon());
        vo.setMenuUrl(menuItem.getMenuUrl());
        vo.setIsExtra(menuItem.getIsExtra());
        return vo;
    }
}